package org.wddsicmd.dev;
import org.wddsicmd.util.Log;
import org.wddsicmd.util.CustomProperties;

import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;

//import org.apache.log4j.Logger;

import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.IDevice;

public class AndroidDeviceManager extends Thread implements AndroidDebugBridge.IDeviceChangeListener, AndroidDebugBridge.IDebugBridgeChangeListener {
	private final static String TAG = "AndroidDeviceManager";

	private StateChangeListener mStateChangeListener;

	public AndroidDeviceManager() {
	}

	public void initManager() {
		AndroidDebugBridge.init(false);
		Runtime.getRuntime().addShutdownHook(this);
		AndroidDebugBridge.addDebugBridgeChangeListener(this);
		AndroidDebugBridge.addDeviceChangeListener(this);
	}


	@Override
	public void run() {
		try {
			AndroidDebugBridge.disconnectBridge();
			AndroidDebugBridge.terminate();
		} catch (Exception e) {
			Log.d(TAG, "Failed to shutdown Android Device Bridge " + e);
		}
	}

	public void createBridge() {
	
		try {
			AndroidDebugBridge.createBridge(getAdbPath(), true);
			Log.d(TAG, "Connected to ADB via " + getSocketAddress());
		} catch (Exception e) {
			throw new RuntimeException("Failed to createBridge");
		}
	}

	@Override
	public void deviceConnected(IDevice dev) {
		Log.d(TAG, "Device connected: " + dev);
		if(mStateChangeListener != null){
			mStateChangeListener.deviceConnected(dev);
		}
	}


	@Override
	public void deviceDisconnected(IDevice dev) {
		Log.d(TAG, "Device disconnected: " + dev);
		if(mStateChangeListener != null){
			mStateChangeListener.deviceDisconnected(dev);
		}		
	}

	public void reloadDevices() {
		for (IDevice dev : AndroidDebugBridge.getBridge().getDevices()) {
			deviceConnected(dev);
		}
	}

	public boolean restartADB() {
		return AndroidDebugBridge.getBridge().restart();
	}

	public boolean isConnectedToADB() {
		return AndroidDebugBridge.getBridge().isConnected();
	}

	public InetSocketAddress getSocketAddress() {
		return AndroidDebugBridge.getSocketAddress();
	}

	@Override
	public void deviceChanged(IDevice dev, int changeMask) {
		Log.d(TAG, "Device changed: " + dev + ", mask=" + toMaskString(changeMask));
	}

	@Override
	public void bridgeChanged(AndroidDebugBridge adb) {
		Log.d(TAG, "ADB changed");
	}

	private String toMaskString(int mask) {
		StringBuilder result = new StringBuilder("");
		if ((mask & IDevice.CHANGE_BUILD_INFO) != 0) {
			result.append("CHANGE_BUILD_INFO ");
		}
		if ((mask & IDevice.CHANGE_CLIENT_LIST) != 0) {
			result.append("CHANGE_CLIENT_LIST ");
		}
		if ((mask & IDevice.CHANGE_STATE) != 0) {
			result.append("CHANGE_STATE ");
		}
		return result.toString();
	}

	public interface StateChangeListener{
		void deviceConnected(IDevice dev);
		void deviceDisconnected(IDevice dev);
	}	
	public void addStateChangeListener(StateChangeListener sc){
		mStateChangeListener = sc;
	}

	public static String getAdbPath(){
		String adbPath = "adb";
		String osStr = System.getProperties().getProperty("os.name");
		if(osStr != null && "Linux".equals(osStr)){
			adbPath = "adb";
		}else{
			adbPath = "c:\\adb\\adb.exe";
		}	
		return adbPath;
	}	
	public static String getBatchPath(){
		String tempDir = CustomProperties.getTempPath();
		String adbPath = tempDir + "/batchCmd.sh";
		String osStr = System.getProperties().getProperty("os.name");
		if(osStr != null && "Linux".equals(osStr)){
			adbPath = tempDir + "/batchCmd.sh";
		}else{
			adbPath = tempDir + "\\batchCmd.bat";
		}	
		return adbPath;
	}	
	public static String getBatchCmd(String batchPath){
		String batchCmd = null;
		String osStr = System.getProperties().getProperty("os.name");
		if(osStr != null && "Linux".equals(osStr)){
			//Runtime.getRuntime().exec("chmod 777 "+batchPath);  
			batchCmd = "bash " + batchPath;
		}else{
			batchCmd = batchPath;
		}
		return batchCmd;
	}	
	public static String getLineSeparator(){
		return System.getProperty("line.separator");
	}
	
}
